﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Linq.Expressions;

namespace ManageStore.Common
{
    public class FlexBindingSource<TDataSource>
    {
        private BindingSource _winFormsBindingSource;
        public FlexBindingSource()
        {
            this._winFormsBindingSource = new BindingSource();
            _winFormsBindingSource.DataSource = typeof(TDataSource);
        }

        /// <summary>
        /// Creates a DataBinding between a control property and a datasource property
        /// </summary>
        /// <typeparam name="TControl">The control type, must derive from System.Winforms.Control</typeparam>
        /// <param name="controlInstance">The control instance on wich the databinding will be added</param>
        /// <param name="controlPropertyAccessor">A lambda expression which specifies the control property to be databounded (something like textboxCtl => textboxCtl.Text)</param>
        /// <param name="datasourceMemberAccesor">A lambda expression which specifies the datasource property (something like datasource => datasource.Property) </param>
        public void CreateBinding<TControl>(TControl controlInstance, Expression<Func<TControl, object>> controlPropertyAccessor, Expression<Func<TDataSource, object>> datasourceMemberAccesor)
            where TControl : Control
        {
            this.CreateBinding(controlInstance, controlPropertyAccessor, datasourceMemberAccesor, DataSourceUpdateMode.OnValidation);
        }

        /// <summary>
        /// Creates a DataBinding between a control property and a datasource property
        /// </summary>
        /// <typeparam name="TControl">The control type, must derive from System.Winforms.Control</typeparam>
        /// <param name="controlInstance">The control instance on wich the databinding will be added</param>
        /// <param name="controlPropertyAccessor">A lambda expression which specifies the control property to be databounded (something like textboxCtl => textboxCtl.Text)</param>
        /// <param name="datasourceMemberAccesor">A lambda expression which specifies the datasource property (something like datasource => datasource.Property) </param>
        /// <param name="dataSourceUpdateMode">See control.DataBindings.Add method </param>
        public void CreateBinding<TControl>(TControl controlInstance, Expression<Func<TControl, object>> controlPropertyAccessor, Expression<Func<TDataSource, object>> datasourceMemberAccesor, DataSourceUpdateMode dataSourceUpdateMode)
            where TControl : Control
        {
            string controlPropertyName = FlexReflector.GetPropertyName(controlPropertyAccessor);
            string sourcePropertyName = FlexReflector.GetPropertyName(datasourceMemberAccesor);
            controlInstance.DataBindings.Add(controlPropertyName, _winFormsBindingSource, sourcePropertyName, true, dataSourceUpdateMode);
        }

        private TDataSource _currentItem = default(TDataSource);
        public TDataSource CurrentItem
        {
            get
            {
                return _currentItem;
            }
            set
            {
                _currentItem = value;

                if (value == null)
                    this._winFormsBindingSource.DataSource = typeof(TDataSource);
                else
                    this._winFormsBindingSource.DataSource = value;
            }
        }
    }
}
